#include "stdafx.h"
#include "TodaySettings.h"

using namespace std;

const WCHAR* BASE_PLUGIN_ADDR = L"Software\\Microsoft\\ManilaToday\\Items";
const WCHAR* BASE_MS_PLUGIN_ADDR = L"Software\\Microsoft\\Today\\Items";
const WCHAR* BASE_MANILA_PAGE_ADDR = L"Software\\Microsoft\\ManilaToday";
const WCHAR* BASE_HTC_MANILA_ADDR = L"Software\\HTC\\Manila";
const WCHAR* PATH_DELIMITER = L"\\";


DWORD ReadPluginDWORDValue(WCHAR *pluginName, WCHAR* value, bool manila);
DWORD ReadPluginWCharValue(WCHAR *pluginName, WCHAR* value, WCHAR* data, int dataLen, bool manila);

DWORD ReadWCharValue(HKEY key, WCHAR* value, WCHAR* data, int dataLen);
DWORD ReadDWORDValue(HKEY key, WCHAR* value);


TODAYTABSETTINGS GetMainSettings()
{
	TODAYTABSETTINGS settings;

	HKEY hKey;
	RegOpenKeyEx(HKEY_LOCAL_MACHINE, BASE_MANILA_PAGE_ADDR, NULL, KEY_READ, &hKey);

	BOOL fUseDefaultBackground = ReadDWORDValue(hKey, L"UseDefaultBackground");

	settings.fOverrideTabHeight = ReadDWORDValue(hKey, L"OverrideTabHeight");
	settings.TabHeight = ReadDWORDValue(hKey, L"TabHeight");
	settings.TabHeightLandscape = ReadDWORDValue(hKey, L"TabHeightLandscape");

	if (fUseDefaultBackground)
	{
		HKEY hKeyHtc;
		RegOpenKeyEx(HKEY_CURRENT_USER, BASE_HTC_MANILA_ADDR, NULL, KEY_READ, &hKeyHtc);
		ReadWCharValue(hKeyHtc, L"HomeBackgroundPath", settings.szBackgroundPath, sizeof(settings.szBackgroundPath));
		RegCloseKey(hKeyHtc);
	}
	else
	{
		ReadWCharValue(hKey, L"BackgroundPath", settings.szBackgroundPath, sizeof(settings.szBackgroundPath));
	}

	ReadWCharValue(hKey, L"TargetPage", settings.szActivePage, sizeof(settings.szActivePage));
	if (wcslen(settings.szActivePage) <= 0)
	{
		wcscpy(settings.szBackgroundPath, L"Manila://today.page");
	}

	RegCloseKey(hKey);

	return settings;
}

list<TODAYLISTITEM>* GetAvailablePlugins()
{
	HKEY itemsKey;
	LONG result = RegOpenKeyEx(HKEY_LOCAL_MACHINE, BASE_MS_PLUGIN_ADDR, 0, KEY_ENUMERATE_SUB_KEYS , &itemsKey);


	list<TODAYLISTITEM>* items = new list<TODAYLISTITEM>();
	int index = 0;
	WCHAR keyName[256];
	DWORD keyLen;
	
	while(1)
	{
		keyLen = 256;
		memset(keyName, 0, keyLen);
		
		LONG result = RegEnumKeyEx(itemsKey, index, keyName, &keyLen, 0, 0, 0, 0);
		if (result != ERROR_SUCCESS)
			break;
		
		TODAYLISTITEM item;
		memset(&item, 0, sizeof(TODAYLISTITEM));
		
		memcpy(item.szName, keyName, min(MAX_ITEMNAME, keyLen) * sizeof(TCHAR)); 
		item.dwOrder = ReadPluginDWORDValue(keyName, L"Order", true);
		item.fEnabled = ReadPluginDWORDValue(keyName, L"Enabled", true);
		item.dwSelectability = ReadPluginDWORDValue(keyName, L"Selectability", false);
		item.grfFlags = ReadPluginDWORDValue(keyName, L"Flags", false);
		item.tlit = (TODAYLISTITEMTYPE) ReadPluginDWORDValue(keyName, L"Type", false);
		item.fOptions = ReadPluginDWORDValue(keyName, L"Options", false);

		ReadPluginWCharValue(keyName, L"DLL", item.szDLLPath, sizeof(item.szDLLPath), false);
		
		items->push_back(item);

		index++;
	}
	return items;
}

HKEY GetPluginBaseKey(WCHAR *pluginName, bool manila)
{
	wstring key;
	key += manila ? BASE_PLUGIN_ADDR : BASE_MS_PLUGIN_ADDR;
	key += PATH_DELIMITER;
	key += pluginName;

	HKEY hKey;
	RegOpenKeyEx(HKEY_LOCAL_MACHINE, key.c_str() , NULL, KEY_QUERY_VALUE, &hKey);
	
	return hKey;
}

DWORD ReadPluginDWORDValue(WCHAR *pluginName, WCHAR* value, bool manila)
{
	return ReadDWORDValue(GetPluginBaseKey(pluginName, manila), value);
}

DWORD ReadPluginWCharValue(WCHAR *pluginName, WCHAR* value, WCHAR* data, int dataLen, bool manila)
{
	return ReadWCharValue(GetPluginBaseKey(pluginName, manila), value, data, dataLen);
}

DWORD ReadDWORDValue(HKEY key, WCHAR* value)
{
	DWORD data;
	DWORD dataLen = sizeof(DWORD);

	DWORD result = RegQueryValueEx(key, value, 0, 0, (BYTE*)&data, &dataLen);
	
	if (result == ERROR_SUCCESS)
		return data;

	return 0;
}

DWORD ReadWCharValue(HKEY key, WCHAR* value, WCHAR* data, int dataLen)
{
	memset(data, 0, dataLen);

	DWORD bytesReaded = dataLen; 

	DWORD result = RegQueryValueEx(key, value, 0, 0, (BYTE*)data, &bytesReaded);

	if (result == ERROR_SUCCESS)
		return bytesReaded;

	return 0;
}